package harnesses;
import static org.junit.Assert.*;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;

public abstract class ConcurrentHarness {
	protected static final int CYCLES = 1000000;
	private static final int THREADS_AMOUNT = 4;
	protected ExecutorService service;
	
	@Before
	public void initExecutor() {
		//service = new ThreadPoolExecutor(THREADS_AMOUNT, THREADS_AMOUNT, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CYCLES));
		service = Executors.newFixedThreadPool(THREADS_AMOUNT);
	}

	protected void submitTasks() {
		try {
			for (int i=0; i<CYCLES; i++) {
				service.submit(newTask());			
			}
		} catch (RejectedExecutionException e) {
			fail("Execution rejected");
		}
	}
	
	@After
	public void collectResults() throws InterruptedException {
		waitAllTasks();
		checkResults();
	}

	private void waitAllTasks() throws InterruptedException {
		service.shutdown();
		boolean terminated = service.awaitTermination(10, TimeUnit.SECONDS);
		assertTrue("Finished all threads", terminated);
	}

	protected abstract Runnable newTask();
	
	protected abstract void checkResults();
}
